package com.droiddata;

import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

public class SQLiteTransactionManager implements ISQLiteTransactionManager {
    private SQLiteOpenHelper dbHelper;
    private TransactionStatus status;
    private SQLiteDatabase db;
    private int frameCount = 0;

    private final Object transactionLock = new Object();

    public SQLiteTransactionManager(SQLiteOpenHelper dbHelper) {
        this.dbHelper = dbHelper;
        this.status = new TransactionStatus(db == null || !db.isOpen());
    }

    public ITransactionStatus getTransactionStatus() {
        return status;
    }

    public SQLiteDatabase beginTransaction() {
        synchronized (transactionLock) {
            frameCount++;
            if (db == null) {
                try {
                    db = dbHelper.getReadableDatabase();
                    db.beginTransaction();
                } catch (SQLiteException e) {
                    Log.e("Error opening database", e.getMessage());
                    e.printStackTrace();
                } catch (IllegalStateException e) {
                    Log.e("Unable to start transaction", e.getMessage());
                    e.printStackTrace();
                }
            }
            return db;
        }
    }

    public void endTransaction() {
        synchronized (transactionLock) {
            if (--frameCount == 0) {
                // FIXME why would the database ever be closed?
                if (!db.isOpen())
                    return;
                if (!status.isRollbackOnly()) {
                    try {
                        db.setTransactionSuccessful();
                        db.endTransaction();
                        db.close();
                    } catch (SQLiteException e) {
                        // this apparently happens sometimes because the db is
                        // closed --
                        // probably a bug in the Android OS
                        Log.e("Unable to end transaction", e.getMessage());
                        e.printStackTrace();
                    } catch (IllegalStateException e) {
                        // this sometimes happens when there is no transaction
                        // pending
                        Log.e("Unable to end transaction", e.getMessage());
                        e.printStackTrace();
                    }
                }

                db = null;
            }
        }
    }
}